﻿using MathNet.Numerics.LinearAlgebra.Factorization;

namespace MicroCloud.Authorization
{
    #region "功能信息基类"
    /// <summary>
    /// 功能信息基类
    /// </summary>
    [DebuggerDisplay("{ToString()}")]
    [EventEntityIgnore]
    [ValueGenerate(ValueGenerateRule.Never, ValueGenerateMode.Snowflake)]
    public abstract class FunctionBase : EntityBase<long>, IFunction, ILockable, ICreatedTime, IUpdatedTime, IDataVersion
    {
        #region "字段"
        /// <summary>
        /// 控制器类型
        /// </summary>
        [NotMapped]
        protected Type _controllerType = null;
        /// <summary>
        /// 功能方法
        /// </summary>
        [NotMapped]
        protected MethodInfo _method = null;
        #endregion

        #region "属性"
        #region "获取或设置 功能名称"
        private string _Name = "";
        /// <summary>
        /// 获取或设置 功能名称
        /// </summary>
        [Column("Name")]
        [Required, DefaultValue("")]
        [StringSize(StringSizeType.Name)]
        [DisplayName("功能名称")]
        public string Name { get { return _Name; } set { _Name = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 区域名称"
        private string _Area = "";
        /// <summary>
        /// 获取或设置 区域名称
        /// </summary>
        [Column("Area")]
        [StringSize(StringSizeType.Name)]
        [DisplayName("区域")]
        public string Area { get { return _Area; } set { _Area = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 控制器名称"
        private string _Controller = "";
        /// <summary>
        /// 获取或设置 控制器名称
        /// </summary>
        [Column("Controller")]
        [StringSize(StringSizeType.Name)]
        [DisplayName("控制器")]
        public string Controller { get { return _Controller; } set { _Controller = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 控制器的功能名称"
        private string _Action = "";
        /// <summary>
        /// 获取或设置 控制器的功能名称
        /// </summary>
        [Column("Action")]
        [StringSize(StringSizeType.Name)]
        [DisplayName("功能")]
        public string Action { get { return _Action; } set { _Action = value.ReplaceNull(); } }
        #endregion
        #region "获取或设置 是否是控制器"
        /// <summary>
        /// 获取或设置 是否是控制器
        /// </summary>
        [Column("IsController")]
        [DisplayName("是否控制器")]
        public bool IsController { get; set; }
        #endregion
        #region "获取或设置 是否Ajax功能"
        /// <summary>
        /// 获取或设置 是否Ajax功能
        /// </summary>
        [Column("IsAjax")]
        [DisplayName("是否Ajax功能")]
        public bool IsAjax { get; set; }
        #endregion
        #region "获取或设置 访问类型"
        /// <summary>
        /// 获取或设置 访问类型
        /// </summary>
        [Column("AccessType")]
        [DisplayName("访问类型")]
        public FunctionAccessType AccessType { get; set; }
        #endregion
        #region "获取或设置 访问类型是否更改，如为true，刷新功能时将忽略功能类型"
        /// <summary>
        /// 获取或设置 访问类型是否更改，如为true，刷新功能时将忽略功能类型
        /// </summary>
        [Column("IsAccessTypeChanged")]
        [DisplayName("访问类型是否更改")]
        public bool IsAccessTypeChanged { get; set; }
        #endregion
        #region "获取或设置 是否启用操作审计"
        /// <summary>
        /// 获取或设置 是否启用操作审计
        /// </summary>
        [Column("AuditOperationEnabled")]
        [DisplayName("是否操作审计")]
        public bool AuditOperationEnabled { get; set; }
        #endregion
        #region "获取或设置 是否启用数据审计"
        /// <summary>
        /// 获取或设置 是否启用数据审计
        /// </summary>
        [Column("AuditEntityEnabled")]
        [DisplayName("是否数据审计")]
        public bool AuditEntityEnabled { get; set; }
        #endregion
        #region "获取或设置 数据缓存时间（秒）"
        /// <summary>
        /// 获取或设置 数据缓存时间（秒）
        /// </summary>
        [Column("CacheExpirationSeconds")]
        [DisplayName("数据缓存秒数")]
        public int CacheExpirationSeconds { get; set; }
        #endregion
        #region "获取或设置 是否相对过期时间，否则为绝对过期"
        /// <summary>
        /// 获取或设置 是否相对过期时间，否则为绝对过期
        /// </summary>
        [Column("IsCacheSliding")]
        [DisplayName("是否相对过期时间")]
        public bool IsCacheSliding { get; set; }
        #endregion
        #region "获取或设置 是否从库读取数据"
        /// <summary>
        /// 获取或设置 是否从库读取数据
        /// </summary>
        [Column("IsSlaveDatabase")]
        [DisplayName("是否从库")]
        public bool IsSlaveDatabase { get; set; }
        #endregion

        #region "获取或设置 是否锁定"
        /// <summary>
        /// 获取或设置 是否锁定
        /// </summary>
        [Column("IsLocked")]
        [DisplayName("是否锁定")]
        public bool IsLocked { get; set; }
        #endregion

        #region "获取或设置 创建时间 ICreatedTime、ICreationAudited  可装载接口，在数据创建时可自动设置当前时间"
        /// <summary>
        /// 获取或设置 创建时间
        /// </summary>
        [Column("CreatedTime")]
        [DisplayName("创建时间")]
        public DateTime CreatedTime { get; set; }
        #endregion

        #region "获取或设置 更新时间 IUpdatedTime、IUpdateAudited 可装载接口，在数据更新时可自动设置当前时间"
        /// <summary>
        /// 获取或设置 更新时间
        /// </summary>
        [Column("UpdatedTime")]
        [DisplayName("更新时间")]
        public DateTime? UpdatedTime { get; set; }
        #endregion

        #region "获取或设置 数据版本 IDataVersion 可装载接口，用于乐观并发处理"
        /// <summary>
        /// 获取或设置 数据版本
        /// 在实体提交验证后（增加、修改）会自动设置一个时间戳值持久化至数据库
        /// 修改、移除时取实体数据库值与提交值比对，如不一致则拒绝提交
        /// </summary>
        [AuditIgnore]
        [Column("DataVersion")]
        [DisplayName("数据版本")]
        public long DataVersion { get; set; }
        #endregion

        #endregion

        #region "方法"
        #region "获取控制器类型"
        /// <summary>
        /// 获取控制器类型
        /// </summary>
        /// <returns>控制器类型</returns>
        public virtual Type ControllerType()
        {
            return _controllerType;
        }
        #endregion
        #region "获取功能方法"
        /// <summary>
        /// 获取功能方法
        /// </summary>
        /// <returns>功能方法</returns>
        public virtual MethodInfo Method()
        {
            return _method;
        }
        #endregion

        #region "返回一个表示当前对象的String"
        /// <summary>
        /// 返回一个表示当前对象的String
        /// </summary>
        /// <returns>表示当前对象的字符串</returns>
        public override string ToString()
        {
            return $"{Name}[{Area}/{Controller}/{Action}]";
        }
        #endregion

        #endregion

    }
    #endregion

}
